﻿using System;
using System.Collections.Generic;
using System.Linq;
using Neturion.Dados;
using Neturion.IRepositorios;
using Neturion.Repositorios;

namespace Neturion.Negocios
{
    /// <summary>
    /// 
    /// </summary>
    public class NegocioPessoa
    {
        private IRepositorioPessoa _repositorioPessoa;
        /// <summary>
        /// 
        /// </summary>
        public NegocioPessoa()
        {
            _repositorioPessoa = new RepositorioPessoa();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pessoa"></param>
        /// <returns></returns>
        public Pessoa Inserir(Pessoa pessoa)
        {
            //A Data do Cadastro será sempre a Data do Dia no Banco de Dados
            //Artificio para salvar Pessoa Fisica Sem CPF
	        if(pessoa.CpfCnpj == "11111111111")
	        {
		        pessoa.CpfCnpj="";
	        }
            pessoa.DataCadastro = DateTime.Now.Date;


            return _repositorioPessoa.Inserir(pessoa);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pessoa"></param>
        /// <returns></returns>
        public Pessoa Atualizar(Pessoa pessoa)
        {
            //Artificio para salvar Pessoa Fisica Sem CPF
            if (pessoa.CpfCnpj == "11111111111")
            {
                pessoa.CpfCnpj = "";
            }
            return _repositorioPessoa.Atualizar(pessoa);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pessoa"></param>
        public void Excluir(Pessoa pessoa)
        {
            Pessoa pessoaTmp = ObterPorId(pessoa.PessoaId);
            _repositorioPessoa.Excluir(pessoaTmp);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IList<Pessoa> ObterTodos()
        {
            return _repositorioPessoa.ObterTodos();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Pessoa ObterPorId(int id)
        {
            return _repositorioPessoa.ObterPorId(id);
        }

        public IList<Pessoa> ObterTodos(int inicio, int quantidade, int quantidadeMinima, Usuario usuarioPermissao, string nomeRazaoSocial, string apelidoFantasia, string nomeReduzido,  string cpfCnpj, Midia midia, EnumTipoPessoa enumTipoPessoa, DateTime? dataNascimentoAbertura, DateTime? inicioVigencia, DateTime? fimVigencia)
        {

            //Realizar regras do usuario Permissão

            return _repositorioPessoa.ObterTodos(inicio, quantidade, quantidadeMinima, 
            nomeRazaoSocial, apelidoFantasia, 
            nomeReduzido,  cpfCnpj, midia, 
            enumTipoPessoa, dataNascimentoAbertura,
            inicioVigencia, fimVigencia);
        }

        public IList<Pessoa> ObterTodos(int inicio, int quantidade, int quantidadeMinima, Usuario usuarioPermissao, string nomeRazaoSocial, string apelidoFantasia, string nomeReduzido, string cpfCnpj, Midia midia, EnumTipoPessoa enumTipoPessoa, EnumTipoSexo enumTipoSexo, EnumEscolaridade enumEscolaridade, EnumEstadoCivil enumEstadoCivil, DateTime? dataNascimentoAberturaDe, DateTime? dataNascimentoAberturaAte, DateTime? cadastroDe, DateTime? cadastroAte, DateTime? inicioVigenciaDe, DateTime? inicioVigenciaAte, DateTime? fimVigenciaDe, DateTime? fimVigenciaAte)
        {
            //Regras de Negocio do Usuário Permissão

            return _repositorioPessoa.ObterTodos(inicio, quantidade, quantidadeMinima,
                nomeRazaoSocial, apelidoFantasia, nomeReduzido, 
                cpfCnpj, midia, enumTipoPessoa, enumTipoSexo, 
                enumEscolaridade, enumEstadoCivil, 
                dataNascimentoAberturaDe, dataNascimentoAberturaAte, 
                cadastroDe, cadastroAte, inicioVigenciaDe, 
                inicioVigenciaAte, fimVigenciaDe, fimVigenciaAte);
        }

        public Pessoa ObterPorCpfCnpj(Usuario usuarioPermissao, string cpfCnpj)
        {
            return _repositorioPessoa.ObterPorCpfCnpj(cpfCnpj);
        }

        public IList<Pessoa> ObterPorDescricao(string descricao)
        {
            return _repositorioPessoa.ObterPorDescricao(descricao);
        }

        public Endereco ObterEnderecoVigentePessoa(Usuario usuarioPermissao, Pessoa pessoa, int tipo)
        {
            if (tipo <= 0)
            {
                throw new Exception("Selecione o Tipo de Endereço!");
            }

            Endereco enderecoPesquisado = null;

            List<Endereco> listaEnderecos = pessoa.ListaEnderecos.Cast<Endereco>().ToList()
                   .Where(endereco => 
                       ( !endereco.FimVigencia.HasValue 
                       || (endereco.FimVigencia.Value.CompareTo(DateTime.Now.Date) <= 0 )))
                       .ToList();

            if ((listaEnderecos == null)&&(listaEnderecos.Count == 0))
            {
                throw new Exception("Pessoa sem Endereços!");
            }
            
            switch (tipo)
            {
                case 1://Cobrança
                    {
                       enderecoPesquisado = listaEnderecos.Where(endereco => endereco.FlagCobranca).FirstOrDefault();
                        break;
                    }
                case 2://Correspondencia
                    {
                        enderecoPesquisado = listaEnderecos.Where(endereco => endereco.FlagCorrespondencia).FirstOrDefault();
                        break;
                    }
                case 3://Faturamento
                    {
                        enderecoPesquisado = listaEnderecos.Where(endereco => endereco.FlagFaturamento).FirstOrDefault();
                        break;
                    }
                case 4://Publicação
                    {
                        enderecoPesquisado = listaEnderecos.Where(endereco => endereco.FlagPublicacao).FirstOrDefault();
                        break;
                    }
            }
            return enderecoPesquisado;
        }

        public Telefone ObterTelefoneVigentePessoa(Usuario usuarioPermissao, Pessoa pessoa, EnumTipoTelefone tipoTelefone)
        {
            return pessoa.ListaTelefones.Cast<Telefone>().ToList()
                    .Where(telefone => (!telefone.FimVigencia.HasValue
                        || (telefone.FimVigencia.Value.CompareTo(DateTime.Now.Date) <= 0))
                        && telefone.EnumTipoTelefone == tipoTelefone)
                    .FirstOrDefault();
        }

        public Email ObterEmailVigentePessoa(Usuario usuarioPermissao, Pessoa pessoa)
        {
            return pessoa.ListaEmails.Cast<Email>().ToList()
                    .Where(email => !email.FimVigencia.HasValue
                        || (email.FimVigencia.Value.CompareTo(DateTime.Now.Date) <= 0))
                    .FirstOrDefault(); 
        }
    }
}